<html>

<head>
    <style>
        body {
            margin: 0;
            background: white;
        }

        .touch-point {
            display: none;
            position: absolute;
            width: 30px;
            height: 30px;
            margin: -15px 0 0 -15px;
            background: rgba(37, 0, 255, 0.3);
            -webkit-border-radius: 50%;
            -moz-border-radius: 50%;
            border-radius: 50%;
            z-index: 2;
        }

        .hide {
            display: none;
        }
    </style>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

    <script src="../node_modules/roslib/build/roslib.min.js"></script>
    <script src="./hexapod.js"></script>
    <script src="./joystickController.js"></script>

</head>

<body>
    <svg viewBox="0 0 600 300" id="amdfc-controller" style="position: absolute; z-index: 1;" scroll="no"
        class="connected">
        <style>
            .amdfc--int:hover {
                fill: rgba(165, 154, 231, 1);
                background: #bbb;
            }

            .amdfc-int.amdfc-active {
                fill: fuchsia;
                fill: rgba(165, 154, 231, 1);
            }
        </style>
        <g fill="#ddd" stroke="#222" stroke-width="3">
            <rect x="150" y="10" width="100" height="100" rx="5" ry="5" class="amdfc-int" id="amdfc-axe-l2"></rect>
            <rect x="350" y="10" width="100" height="100" rx="5" ry="5" class="amdfc-int" id="amdfc-axe-r2"></rect>
            <rect x="100" y="25" width="100" height="40" rx="5" ry="5" class="amdfc-int" id="amdfc-button-4"></rect>
            <rect x="400" y="25" width="100" height="40" rx="5" ry="5" class="amdfc-int" id="amdfc-button-5"></rect>
            <path d="M135,50 C 45,50 20,180 20,240 20,300 80,330 175,220 175,220 
            425,220 425,220 520,330 580,300 580,240 580,180 555,50 465,50 Z"></path>
            <circle cx="200" cy="200" r="35" id="amdfc-axe-left"></circle>
            <circle cx="400" cy="200" r="35" id="amdfc-axe-right"></circle>
            <circle cx="200" cy="200" r="15" class="amdfc-int" id="amdfc-button-l3"></circle>
            <circle cx="400" cy="200" r="15" class="amdfc-int" id="amdfc-button-r3"></circle>
            <!-- <path d="M190,182 210,182 200,168 Z" stroke-width="0" class="amdfc-int" id="amdfc-axe-0-up"></path>
            <path d="M190,218 210,218 200,232 Z" stroke-width="0" class="amdfc-int" id="amdfc-axe-0-down"></path>
            <path d="M218,190 218,210 232,200 Z" stroke-width="0" class="amdfc-int" id="amdfc-axe-0-right"></path>
            <path d="M182,190 182,210 168,200 Z" stroke-width="0" class="amdfc-int" id="amdfc-axe-0-left"></path>
            <path d="M390,182 410,182 400,168 Z" stroke-width="0" class="amdfc-int" id="amdfc-axe-1-up"></path>
            <path d="M390,218 410,218 400,232 Z" stroke-width="0" class="amdfc-int" id="amdfc-axe-1-down"></path>
            <path d="M418,190 418,210 432,200 Z" stroke-width="0" class="amdfc-int" id="amdfc-axe-1-right"></path>
            <path d="M382,190 382,210 368,200 Z" stroke-width="0" class="amdfc-int" id="amdfc-axe-1-left"></path> -->

            <circle cx="480" cy="160" r="15" class="amdfc-int" id="amdfc-button-0"></circle>
            <circle cx="510" cy="130" r="15" class="amdfc-int" id="amdfc-button-1"></circle>
            <circle cx="450" cy="130" r="15" class="amdfc-int" id="amdfc-button-2"></circle>
            <circle cx="480" cy="100" r="15" class="amdfc-int" id="amdfc-button-3"></circle>

            <rect x="105" y="85" width="30" height="90" fill="#aaa" stroke="#aaa"></rect>
            <rect x="75" y="115" width="90" height="30" fill="#aaa" stroke="#aaa"></rect>

            <path d="M120,85 105,115 135,115 Z" stroke-width="0" class="amdfc-int" id="amdfc-axe-0-up"></path>
            <path d="M120,175 105,145 135,145 Z" stroke-width="0" class="amdfc-int" id="amdfc-axe-0-down"></path>
            <path d="M75,130 105,115 105,145 Z" stroke-width="0" class="amdfc-int" id="amdfc-axe-0-left"></path>
            <path d="M165,130 135,115 135,145 Z" stroke-width="0" class="amdfc-int" id="amdfc-axe-0-right"></path>

            <rect x="245" y="145" width="50" height="18" rx="9" ry="9" class="amdfc-int" id="amdfc-button-select">
            </rect>
            <rect x="305" y="145" width="50" height="18" rx="9" ry="9" class="amdfc-int" id="amdfc-button-start"></rect>

            <!-- <circle cx="120" cy="160" r="15" class="amdfc-int" id="amdfc-button-13"></circle>
            <circle cx="90" cy="130" r="15" class="amdfc-int" id="amdfc-button-14"></circle>
            <circle cx="150" cy="130" r="15" class="amdfc-int" id="amdfc-button-15"></circle>
            <circle cx="120" cy="100" r="15" class="amdfc-int" id="amdfc-button-12"></circle> -->

            <circle cx="300" cy="90" r="20" class="amdfc-int" id="amdfc-button-center"></circle>
        </g>
        <g dominant-baseline="middle" text-anchor="middle" fill="#222" font-size="16" font-family="Arial,sans-serif"
            style="user-select: none; pointer-events: none;">
            <text x="480" y="160">0</text>
            <text x="510" y="130">1</text>
            <text x="450" y="130">2</text>
            <text x="480" y="100">3</text>
            <text x="150" y="40">4</text>
            <text x="450" y="40">5</text>
            <text x="225" y="30">L2</text>
            <text x="375" y="30">R2</text>
            <text x="270" y="156">6</text>
            <text x="330" y="156">7</text>
            <text x="200" y="200">9</text>
            <text x="400" y="200">10</text>
            <!-- <text x="120" y="100">12</text>
            <text x="120" y="160">13</text>
            <text x="90" y="130">14</text>
            <text x="150" y="130">15</text> -->
            <text x="300" y="90">8</text>
            <text x="270" y="175" font-size="10">SELECT</text>
            <text x="330" y="175" font-size="10">START</text>
        </g>
    </svg>
    <div id="touch-point" class="touch-point"></div>
    <script>

        let joyController = new JoystickController()

        let default_state = {
            Axes: [0, 0, -32767, 0, 0, -32767, 0, 0],
            Buttons: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        }
        let joy_state = JSON.parse(JSON.stringify(default_state))
        const axes_map = {
            "amdfc-axe-0-up": { id: 7, value: -32767, default: 0 },
            "amdfc-axe-0-down": { id: 7, value: 32767, default: 0 },
            "amdfc-axe-0-left": { id: 6, value: -32767, default: 0 },
            "amdfc-axe-0-right": { id: 6, value: 32767, default: 0 },
            "amdfc-axe-l2": { id: 2, value: 32767, default: -32767 },
            "amdfc-axe-r2": { id: 2, value: 32767, default: -32767 },
        }
        const button_map = {
            "amdfc-button-0": { id: 0, value: 1, default: 0 },
            "amdfc-button-1": { id: 1, value: 1, default: 0 },
            "amdfc-button-2": { id: 2, value: 1, default: 0 },
            "amdfc-button-3": { id: 3, value: 1, default: 0 },
            "amdfc-button-4": { id: 4, value: 1, default: 0 },
            "amdfc-button-5": { id: 5, value: 1, default: 0 },
            "amdfc-button-select": { id: 6, value: 1, default: 0 },
            "amdfc-button-start": { id: 7, value: 1, default: 0 },
            "amdfc-button-center": { id: 8, value: 1, default: 0 },
            "amdfc-button-l3": { id: 9, value: 1, default: 0 },
            "amdfc-button-r3": { id: 10, value: 1, default: 0 },
        }

        let controller = document.querySelector('#amdfc-controller')
        let buttons = document.querySelectorAll('.amdfc-int')
        let tp = document.getElementById("touch-point");
        let last_state = ''

        function publishJoyState(state) {
            msg = {
                data: JSON.stringify(state)
            }
            if (last_state != msg.data) {
                last_state = msg.data
                console.log(msg)
                joyController.onJoyMessage(msg)
                /* //Do not publish joy msg
                if (joyController.joyTopic) {
                    joyController.joyTopic.publish(msg)
                    // joyController.joyTopic.publish(new ROSLIB.Message(msg))
                }
                */
            }
        }

        function buttonDown(e) {
            let name = e.target.id
            if (axes_map[name] || button_map[name]) {
                if (axes_map[name]) { // treat as axes
                    let ele = axes_map[name]
                    joy_state.Axes[ele.id] = ele.value
                } else if (button_map[name]) { // treat as button
                    let ele = button_map[name]
                    joy_state.Buttons[ele.id] = ele.value
                }
                publishJoyState(joy_state)
                e.target.classList.add('amdfc-active')
            }
        }

        function buttonUp(e) {
            console.log('button up')
            let name = e.target.id
            if (name == "amdfc-button-center") {
                return
            }
            if (axes_map[name] || button_map[name]) {
                if (axes_map[name]) { // treat as axes
                    let ele = axes_map[name]
                    joy_state.Axes[ele.id] = ele.default
                } else if (button_map[name]) { // treat as button
                    let ele = button_map[name]
                    joy_state.Buttons[ele.id] = ele.default
                }
                e.target.classList.remove('amdfc-active')
            }
            publishJoyState(joy_state)
        }

        function onButtonClick(e) {
            console.log('button click')
            // console.log(e)
            let name = e.target.id
            if (name == "amdfc-button-center") {
                if (joy_state.Buttons[8] == button_map[name].value) {
                    joy_state.Buttons[8] = button_map[name].default
                    e.target.classList.remove('amdfc-active')
                    for (let i = 0; i < buttons.length; i++) {
                        buttons[i].classList.remove('amdfc-active')
                    }
                    tp.style.display = "none";
                    joy_state = JSON.parse(JSON.stringify(default_state))
                } else {
                    joy_state.Buttons[8] = button_map[name].value
                    e.target.classList.add('amdfc-active')
                }
                publishJoyState(joy_state)
                return
            }

            if (joy_state.Buttons[8] == 0) {
                return
            }

            if (axes_map[name]) { // treat as axes
                let ele = axes_map[name]
                if (joy_state.Axes[ele.id] == ele.value) { //has been pressed, release it
                    joy_state.Axes[ele.id] = ele.default
                    e.target.classList.remove('amdfc-active')
                } else {
                    joy_state.Axes[ele.id] = ele.value
                    e.target.classList.add('amdfc-active')
                }
            } else if (button_map[name]) { // treat as button
                let ele = button_map[name]
                if (joy_state.Buttons[ele.id] == ele.value) { //has been pressed, release it
                    joy_state.Buttons[ele.id] = ele.default
                    e.target.classList.remove('amdfc-active')
                } else {
                    joy_state.Buttons[ele.id] = ele.value
                    e.target.classList.add('amdfc-active')
                }
            }
            publishJoyState(joy_state)

        }

        for (let i = 0; i < buttons.length; i++) {
            const button = buttons[i];
            console.log(button.id)
            button.onclick = onButtonClick
        }

        function init() {

            let left_joy = document.querySelector('#amdfc-axe-left')
            let right_joy = document.querySelector('#amdfc-axe-right')
            const view_width = 600
            let width = controller.clientWidth
            let left_center = {
                x: 200 * width / view_width,
                y: 200 * width / view_width
            }
            let right_center = {
                x: 400 * width / view_width,
                y: 200 * width / view_width
            }
            let radius = 35 * width / view_width
            let max_dist = (35 + 10) * width / view_width

            function distance(p1, p2) {
                return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2))
            }

            function remapAxis(n, max_value = 32767) {
                if (Math.abs(n) > 1) {
                    n = n > 0 ? 1 : -1
                }
                return parseInt(n * max_value)
            }

            function moveToPoint(p) {
                // console.log(distance(left_center, p), distance(right_center, p))
                let left_move = distance(left_center, p) <= max_dist
                let right_move = distance(right_center, p) <= max_dist
                if (left_move || right_move) {
                    // console.log(distance(left_center, p))
                    tp.style.left = p.x + "px";
                    tp.style.top = p.y + "px";
                    tp.style.display = "block";

                    if (tp.classList.contains('hide')) {
                        tp.classList.remove('hide')
                    }

                    if (left_move) {
                        let a0 = (p.x - left_center.x) / radius
                        let a1 = (p.y - left_center.y) / radius
                        joy_state.Axes[0] = remapAxis(a0)
                        joy_state.Axes[1] = remapAxis(a1)
                    } else {
                        let a0 = (p.x - right_center.x) / radius
                        let a1 = (p.y - right_center.y) / radius
                        joy_state.Axes[3] = remapAxis(a0)
                        joy_state.Axes[4] = remapAxis(a1)
                    }
                    publishJoyState(joy_state)
                } else {

                }
            }

            function onMouseDown(e) {
                console.log('mouse down')
                // console.log(e)
                let p = {
                    x: e.offsetX,
                    y: e.offsetY
                }
                if (!button_map[e.target.id] && !axes_map[e.target.id]) {
                    moveToPoint(p)
                }
                else if (e.target.id != "amdfc-button-center" && joy_state.Buttons[8] == 0) {
                    buttonDown(e)
                }

                // console.log(distance(left_center, p))
                document.onmousemove = (e) => {
                    let p = {
                        x: e.offsetX,
                        y: e.offsetY
                    }
                    moveToPoint(p)
                }
            }
            function onMouseUp(e) {
                console.log('mouse up')
                // console.log(e)
                document.onmousemove = null
                tp.style.display = "none";
                joy_state.Axes[0] = 0
                joy_state.Axes[1] = 0
                joy_state.Axes[3] = 0
                joy_state.Axes[4] = 0
                if (e.target.id == "amdfc-button-center") {
                    return
                } else if (joy_state.Buttons[8] == 0) {
                    buttonUp(e)
                } else {
                    publishJoyState(joy_state)
                }

            }
            document.onmousedown = onMouseDown
            document.onmouseup = onMouseUp
            document.ontouchstart = (e) => {
                console.log('touchstart', 'keydown')
                // console.log(e)
                // e.stopPropagation()
                onMouseDown(e)
                try {
                    e.preventDefault()
                } catch (error) {
                    console.log(error)
                }
            }

            document.ontouchend = (e) => {
                console.log('touchend', 'keyup')
                // console.log(e)
                // e.stopPropagation()
                onButtonClick(e)
                onMouseUp(e)
                try {
                    e.preventDefault()
                } catch (error) {
                    console.log(error)
                }
            }

            document.ontouchmove = (e) => {
                // console.log(e);
                let p = {
                    x: e.touches[0].clientX,
                    y: e.touches[0].clientY
                }
                moveToPoint(p)
            };
        }

        document.onclick = () => {
            document.documentElement.requestFullscreen().then(() => {
                if (document.documentElement.offsetWidth / 2 < document.documentElement.offsetHeight) {
                    controller.style.width = "100%"
                } else {
                    controller.style.height = "100%"
                }
                init()
            })
            document.onclick = null
        }

    </script>
</body>

</html>